package logic

import (
	"ahutoj/web/utils"
	"encoding/json"
	"errors"
	"net/http"
)

var chatHeaders = map[string]string{
	"User-Agent":      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0",
	"Accept":          "*/*",
	"Accept-Encoding": "gzip, deflate, br",
	"Connection":      "keep-alive",
	"Content-Type":    "application/json",
}

type ModelType string

var Deep ModelType = "deepseek-coder"

var ChatMap = map[ModelType]Chater{
	Deep: &DeepSeek{},
}

type Chater interface {
	Chat(message []string) (*http.Response, error)
	Open() error
	Close() error
	GetAvailable() bool
}

type Message struct {
	Content string `json:"content"`
	Role    string `json:"role"`
}

type RequestBody struct {
	Messages  *[]Message `json:"messages"`
	Model     string    `json:"model"`
	MaxTokens int64     `json:"max_tokens"`
}

type DeepSeek struct {
	Available     bool
	*utils.AIChat //为以后
	Header        map[string]string
}

func (ds *DeepSeek) Chat(message []string) (*http.Response, error) { //能减少拷贝的代价？
	logger := utils.GetLogInstance()
	if !ds.Available {
		return nil, errors.New("该模型未开启")
	}
	msg:=make([]Message,0,len(message))
	for _,m := range message {
		msg = append(msg,Message{
			Content: m,
			Role:    ds.Role,
		})
	}
	req := &RequestBody{
		Messages: &msg,
		Model:     string(Deep),
		MaxTokens: ds.MaxTokens,
	}
	jsonBody, err := json.Marshal(req)
	if err != nil {
		logger.Errorf("failed to marshal request body: %v", err)
		return nil, err
	}
	body := string(jsonBody)
	resp, err := utils.DoRequest(utils.POST, ds.BaseURL, ds.Header, nil, &body,utils.WithoutRedirect)
	if err != nil {
		logger.Errorf("failed to send request: %v", err)
		return nil, err
	}
	return resp, nil
}

func (ds *DeepSeek) Open() error {
	ds.Available = true
	if ds.Header == nil {
		ds.AIChat = utils.GetConfInstance().AIChat
		ds.Header = make(map[string]string)
		for k, v := range chatHeaders {
			ds.Header[k] = v
		}
		ds.Header["Authorization"] = "Bearer " + ds.ApiKey
	}
	return nil
}

func (ds *DeepSeek) Close() error {
	ds.Available = false
	return nil
}

func (ds *DeepSeek) GetAvailable() bool {
	return ds.Available
}